package com.tstudy.laoshibang.db;

import java.sql.SQLException;
import java.sql.Savepoint;
import java.util.List;
import java.util.Map;

import com.j256.ormlite.android.AndroidDatabaseConnection;
import com.j256.ormlite.dao.Dao;
import com.j256.ormlite.dao.GenericRawResults;
import com.tstudy.laoshibang.utils.LogUtil;

import android.annotation.SuppressLint;

@SuppressLint("DefaultLocale")
public class DBManagerImpl implements DBManager{
	@SuppressWarnings("rawtypes")
	protected Dao dao;
	@SuppressWarnings("rawtypes")
	Class clazz;
	public DBManagerImpl(){
		
	}
	@SuppressWarnings({ "rawtypes" })
	public DBManagerImpl(Class clazz){
		this.clazz = clazz;
		dao = DaoFactory.getInstance().getDao(clazz);
	}
	
	public boolean insert(Object obj){
		boolean result = false;
		try {
			@SuppressWarnings("unchecked")
			int create = dao.create(obj);
			result = create > 0 ?true:false;
		} catch (Exception e) {
			// TODO Auto-generated catch block
			LogUtil.e("insert exception " + e.getMessage());
			e.printStackTrace();
		}
		return result;
	}
	@SuppressWarnings("unchecked")
	public boolean insert(List<?> list){
		boolean result = false;
		int size = list.size();
		LogUtil.d("insert" + "create size == " + size);
		try {
			for (int i = 0; i < size; i++) {
				int create = dao.create(list.get(i));
				LogUtil.d("insert" + "create result == " + create);
				if(create <= 0){
					result = false;
					continue;
				}else{
					result = true;
				}
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			LogUtil.e("insert" + "insert exception " + e.getMessage());
			e.printStackTrace();
		}
		return result;
	}
	@SuppressWarnings("unchecked")
	public boolean insertOrUpdate(List<?> list){
		boolean result = false;
		int size = list.size();
		AndroidDatabaseConnection connection = null;  
        String pointName = "pointName";  
        Savepoint savepoint = null;  
		try {
			connection = new AndroidDatabaseConnection(DaoFactory.getInstance().getHelper().getWritableDatabase(),true);  
            dao.setAutoCommit (connection,false);  
            savepoint = connection.setSavePoint(pointName);  
			for (int i = 0; i < size; i++) {
				Dao.CreateOrUpdateStatus status = dao.createOrUpdate(list.get(i));
				int create = status.getNumLinesChanged();
				if(create <= 0){
					result = false;
					break;
				}else{
					result = true;
				}
			}
			connection.commit(savepoint);  
		} catch ( SQLException e ){  
            LogUtil.e ( "--database create or update exception" ,e);  
            e.printStackTrace();
            try{  
                connection.rollback (savepoint);  
            }catch ( SQLException e1 ){  
            }  
            result = false;
        }finally{
        	try {
        		connection.setAutoCommit(true);//必须加上这句，否则数据库被锁，其他process无法打开
				LogUtil.e ( "--database finally execute ");  
			} catch (Exception e) {
				e.printStackTrace();
			}
        }
		return result;
	}
	@SuppressLint("DefaultLocale")
	public boolean clear(Class<?> clazz){
		boolean result = false;
		try {
			int deleteCount = dao.executeRaw("delete from " + clazz.getSimpleName());
			result = deleteCount > 0 ?true:false;
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return result;
	}
	
	@SuppressWarnings("unchecked")
	public int getCount(){
		int count = 0;
		try {
			GenericRawResults<String[]> rawResults = dao.queryRaw("select count(*) from " + clazz.getSimpleName());
			for (String[] resultArray : rawResults) {
				LogUtil.d(clazz.getSimpleName() + " count==" +  resultArray[0]);
				count = Integer.parseInt(resultArray[0]);
			}
			rawResults.close();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return count;
	}
	
	public void clearTable(Class<?> clazz){
		try {
			dao.executeRaw("delete from " + clazz.getSimpleName());
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
	
	public boolean insertOrUpdate(Object obj){
		boolean result = false;
		try {
			@SuppressWarnings("unchecked")
			Dao.CreateOrUpdateStatus status = dao.createOrUpdate(obj);
			int create = status.getNumLinesChanged();
			result = create > 0 ?true:false;
		} catch (Exception e) {
			LogUtil.e("insertOrUpdate exception " + e.getMessage());
			e.printStackTrace();
		}
		return result;
	}
	
	public boolean delete(Object obj){
		boolean result = false;
		try {
			@SuppressWarnings("unchecked")
			int create = dao.delete(obj);
			result = create > 0 ?true:false;
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return result;
	}
	public boolean deleteById(Object obj){
		boolean result = false;
		try {
			@SuppressWarnings("unchecked")
			int create = dao.deleteById(obj);
			result = create > 0 ?true:false;
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return result;
	}
	
	@SuppressLint("DefaultLocale")
	public boolean deleteByCurrentUserId(String currentUserId){
		boolean result = false;
		try {
			LogUtil.d("deleteByCurrentUserId::" + "delete table name ==" + clazz.getSimpleName().toLowerCase() + "--currentUserId==" + currentUserId);
			int deleteCount = dao.executeRaw("delete from " + clazz.getSimpleName().toLowerCase() + " where currentUserId='" + currentUserId + "'");
			result = deleteCount > 0 ?true:false;
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return result;
	}
	
	@SuppressWarnings("unchecked")
	public boolean update(Object obj){
		boolean result = false;
		try {
			int create = dao.update(obj);
			result = create > 0 ?true:false;
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		LogUtil.d(obj + "update " + result);
		return result;
	}
	@SuppressWarnings("unchecked")
	@Override
	public Object queryById(Object id) {
		Object obj = null;
		try {
			obj = dao.queryForId(id);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return obj;
	}
	
	@Override
	public List<?> queryRaw(String query, String... args) {
		List<?> list = null;
		try {
			list =  (List<?>) dao.queryRaw(query, args);
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return list;
	}
	
	@Override
	public List<?> queryAll() {
		List<?> list = null;
		try {
			list =  (List<?>) dao.queryForAll();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return list;
	}
	@Override
	public int executeRaw(String sql, String... args) {
		int result = 0;
		try {
			result = dao.executeRaw(sql, args);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return result;
	}
	
	@Override
	public int updateRaw(String sql, String... args) {
		int result = 0;
		try {
			result = dao.executeRaw(sql, args);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return result;
	}
	
	
	@SuppressWarnings("rawtypes")
	@Override
	public List queryByField(String fieldName, Object value) {
		List list = null;
		try {
			list =  dao.queryForEq(fieldName, value);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return list;
	}
	
	
	@Override
	@SuppressWarnings({ "rawtypes"})
	public Object queryByFieldFirst(String fieldName, Object value) {
		List list = null;
		try {
			list =  dao.queryForEq(fieldName, value);
			if(list != null && list.size() > 0){
				return list.get(0);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return null;
	}
	
	@SuppressWarnings({ "rawtypes", "unchecked" })
	@Override
	public List queryByFields(Map<String, Object> args) {
		List list = null;
		try {
			list =  dao.queryForFieldValues(args);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return list;
	}
	
	
	@SuppressWarnings({ "rawtypes", "unchecked" })
	@Override
	public Object queryByFieldsFirst(Map<String, Object> args) {
		List list = null;
		try {
			list =  dao.queryForFieldValues(args);
			if(list != null && list.size() > 0){
				return list.get(0);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return null;
	}
	
	@SuppressWarnings({ "rawtypes" })
	@Override
	public List queryBuilderRaw(String order,boolean desc,String where,String whereValue) {
		List list = null;
		try {
			list =  dao.queryBuilder().orderBy(order, true).where().eq(where, whereValue).query();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return list;
	}
}
